function [rect, positions, fps] = color_tracker(params)

% [positions, fps] = color_tracker(params)

% parameters
padding = params.padding;
output_sigma_factor = params.output_sigma_factor;
sigma = params.sigma;
lambda = params.lambda;
learning_rate = params.learning_rate;

target_hist_rate = 0.07;

video_path = params.video_path;
img_files = params.img_files;
pos = floor(params.init_pos);
target_sz = floor(params.wsize);

visualization = params.visualization;

num_frames = numel(img_files);

% window size, taking padding into account
sz = floor(target_sz * (1 + padding));

% desired output (gaussian shaped), bandwidth proportional to target size
output_sigma = sqrt(prod(target_sz)) * output_sigma_factor;
[rs, cs] = ndgrid((1:sz(1)) - floor(sz(1)/2), (1:sz(2)) - floor(sz(2)/2));
y = exp(-0.5 / output_sigma^2 * (rs.^2 + cs.^2));
yf = single(fft2(y));

% store pre-computed cosine window
cos_window = single(hann(sz(1)) * hann(sz(2))');

% to calculate precision
rect = zeros(numel(img_files), 4);
positions = zeros(numel(img_files), 4);

% to calculate fps
time = 0;

for frame = 1:num_frames,
    % load image
    im = imread([video_path img_files{frame}]);
    
    tic;
    
    if frame > 1
        % compute the compressed learnt appearance
        %zp = feature_projection(z_npca, z_pca, projection_matrix, cos_window);
        
        % extract the feature map of the local image patch
        %[xo_npca, xo_pca] = get_subwindow(im, pos, sz, non_compressed_features, compressed_features, w2c);
        x = get_subwindow(im, pos, sz, target_sz, target_hist, cos_window);
        
        
        % do the dimensionality reduction and windowing
        %x = feature_projection(xo_npca, xo_pca, projection_matrix, cos_window);
        
        % calculate the response of the classifier
        kf = fft2(dense_gauss_kernel(sigma, x, z));
        response = real(ifft2(alphaf_num .* kf ./ alphaf_den));
        
        % target location is at the maximum response
        [row, col] = find(response == max(response(:)), 1);
        pos = pos - floor(sz/2) + [row, col];
    end
    
    if size(im, 3)==3
        new_target_hist = get_target_hist(im, pos, target_sz);

        if frame == 1
            target_hist = new_target_hist;
        else
            target_hist = (1-target_hist_rate)*target_hist + target_hist_rate*new_target_hist;
        end
    else
        target_hist = [];
    end
    
    
    % project the features of the new appearance example using the new
    % projection matrix
    %x = feature_projection(xo_npca, xo_pca, projection_matrix, cos_window);
    
    x = get_subwindow(im, pos, sz, target_sz, target_hist, cos_window);
    
    % calculate the new classifier coefficients
    kf = fft2(dense_gauss_kernel(sigma, x));
    new_alphaf_num = yf .* kf;
    new_alphaf_den = kf .* (kf + lambda);
    
    if frame == 1
        % first frame, train with a single image
        alphaf_num = new_alphaf_num;
        alphaf_den = new_alphaf_den;
        z = x;
    else
        % subsequent frames, update the model
        alphaf_num = (1 - learning_rate) * alphaf_num + learning_rate * new_alphaf_num;
        alphaf_den = (1 - learning_rate) * alphaf_den + learning_rate * new_alphaf_den;
        z = (1 - learning_rate) * z + learning_rate * x;
    end
    
    %save position
    positions(frame,:) = [pos target_sz];
    rect(frame,:) = [pos([2,1]) - floor(target_sz([2,1])/2), target_sz([2,1])];
    
    time = time + toc;
    
    %visualization
    if visualization == 1
        rect_position = [pos([2,1]) - target_sz([2,1])/2, target_sz([2,1])];
        if frame == 1,  %first frame, create GUI
            figure('Name',['Tracker - ' video_path]);
            im_handle = imshow(uint8(im), 'Border','tight', 'InitialMag', 100 + 100 * (length(im) < 500));
            rect_handle = rectangle('Position',rect_position, 'EdgeColor','g');
            text_handle = text(10, 10, int2str(frame));
            set(text_handle, 'color', [0 1 1]);
            
            if size(im,3)==3
                figure;
                subplot(141)
                subplot(141)
                h1 = imshow(x(:,:,1)+0.5);
                subplot(142);
                h2 = imshow(x(:,:,2));
                subplot(143);
                h3 = imshow(x(:,:,3));
                subplot(144);
                h4 = imshow(x(:,:,4));
            end
        else
            try  %subsequent frames, update GUI
                set(im_handle, 'CData', im)
                if size(im,3)==3
                    set(h1, 'CData', x(:,:,1)+0.5);
                    set(h2, 'CData', x(:,:,2));
                    set(h3, 'CData', x(:,:,3));
                    set(h4, 'CData', x(:,:,4));
                end
                set(rect_handle, 'Position', rect_position)
                set(text_handle, 'string', int2str(frame));
            catch
                return
            end
        end
        
        drawnow
%         pause
    end
end

fps = num_frames/time;
end